package com.lpf;

import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.ParseTreeWalker;

public class Main {

    public static void main(String[] args) {

        // 这里处理的是"1+2"这一行计算器语言，读取得到字节流
        ANTLRInputStream input = new ANTLRInputStream("1+2");

        // 创建 CalculatorLexer，词法分析器(Lexer)识别字节流得到 Token 流
        CalculatorLexer lexer = new CalculatorLexer(input);
        CommonTokenStream tokens = new CommonTokenStream(lexer);

        // 创建 CalculatorParser，语法分析器(Parser)识别 Token 流得到 AST
        CalculatorParser parser = new CalculatorParser(tokens);
        ParseTree tree = parser.line();

        // 遍历 AST 中各个节点回调 PrintListener 中相应的方法
        ParseTreeWalker walker = new ParseTreeWalker();
        walker.walk(new PrintListener(), tree);

        // 将整个 AST 转换成字符串输出
        System.out.println(tree.toStringTree(parser));
    }

    // 輸出如下：
    // enterEveryRule:1+2<EOF>
    // enterLine:1+2<EOF>   # 开始遍历 line: 1+2
    // enterEveryRule:1+2
    // enterExpr:1+2   # 开始遍历 expr: 1+2
    // enterEveryRule:1
    // enterExpr:1  # 开始遍历 expr: 1
    // visitTerminal:1
    // exitExpr:1   # 结束遍历 expr: 1
    // exitEveryRule:1
    // visitTerminal:+
    // enterEveryRule:2
    // enterExpr:2   # 开始遍历 expr: 2
    // visitTerminal:2
    // exitExpr:2    # 结束遍历 expr: 2
    // exitEveryRule:2
    // exitExpr:1+2  # 结束遍历 expr: 1+2
    // exitEveryRule:1+2
    // visitTerminal:<EOF>
    // exitEveryRule:1+2<EOF>
    // (line (expr (expr 1) + (expr 2)) <EOF>)

}